package org.firefly.db.dialect;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.firefly.db.meta.ColumnMeta;
import org.firefly.db.meta.TableMeta;

/**
 * Oracle 数据库方言
 * @author firefly
 *
 */
public class DerbyDialect extends DialectImpl {
	
	
//	private static Map<String,Class<?>> types = new HashMap<String,Class<?>>();
//	
//	static{
//		types.put("char", Character.class);
//		types.put("varchar", String.class);
//		types.put("boolean", Boolean.class);
//		types.put("integer", Integer.class);
//		types.put("bigint", BigInteger.class);
//		types.put("numeric", Float.class);
//		types.put("decimal", Float.class);
//		types.put("clob", Clob.class);
//		types.put("bolb", Blob.class);
//		types.put("long", Long.class);
//		types.put("timestamp", Date.class);
//	}
	private static Map<Integer,String> types = new HashMap<Integer,String>();
	
	static{
		types.put(Types.CHAR, "char");
		types.put(Types.VARCHAR, "varchar");
		types.put(Types.NVARCHAR, "varchar");
		types.put(Types.NUMERIC, "numeric");
		types.put(Types.DECIMAL, "decimal");
		types.put(Types.FLOAT, "decimal");
		types.put(Types.INTEGER, "integer");
		types.put(Types.BIGINT, "bigint");
		types.put(Types.CLOB, "clob");
		types.put(Types.BLOB, "blob");
		types.put(Types.VARBINARY, "long varchar");
		types.put(Types.DATE, "date");
		types.put(Types.TIMESTAMP, "timestamp");
	}
	
//	final String getTableMetasSQL = "select TABLENAME from \"SYS\".\"SYSTABLES\" where tabletype='T'";
//	@Override
//	public List<TableMeta> getTableMetas() throws SQLException{
//		List<TableMeta> ls = new ArrayList<TableMeta>(); 
//		Statement s = c.createStatement();
//		ResultSet rs = s.executeQuery(getTableMetasSQL);
//		try{
//			while(rs.next()){
//				String tableName = rs.getString("TABLENAME");
//				List<ColumnMeta> colMetas = getColumnMetas(tableName);
//				TableMeta tm = new TableMeta();
//				tm.setName(tableName);
//				tm.setColumnMetaLs(colMetas);
//				ls.add(tm);
//			}
//		}finally{
//			rs.close();
//			s.close();
//		}
//		return ls;
//	}
	
//	final String getColumnMetasSQL = "select COLUMNNAME,cast(COLUMNDATATYPE as varchar(100)) COLUMNMSG from \"SYS\".\"SYSCOLUMNS\" c inner join \"SYS\".\"SYSTABLES\" t on c.REFERENCEID=t.TABLEID and t.tablename=? order by c.COLUMNNUMBER";
//	final Pattern colTypeP = Pattern.compile("(\\w+)");
//	final Pattern colLengthP = Pattern.compile("\\w+\\((.*?)\\)");
//	@Override
//	public List<ColumnMeta> getColumnMetas(String tableName) throws SQLException{
//		List<ColumnMeta> ls = new ArrayList<ColumnMeta>(); 
//		PreparedStatement ps = c.prepareStatement(getColumnMetasSQL);
//		ps.setString(1, tableName);
//		ResultSet rs = ps.executeQuery();
//		try{
//			while(rs.next()){
//				String columnName = rs.getString("COLUMNNAME");
//				//格式type(length) not null
//				String tmp = rs.getString("COLUMNMSG");
//				boolean nullable = tmp.indexOf("NOT NULL")==-1;
//				Matcher mType = colTypeP.matcher(tmp);
//				String sqlType = null;
//				if(mType.find()){
//					sqlType = mType.group(1);
//				}else{
//					System.err.println("无法获取类型，代码:["+tmp+"]");
//				}
//				Class<?> javaType = sqlType2JavaType(sqlType);
//				ColumnMeta cm = new ColumnMeta();
//				cm.setColumnName(columnName);
//				cm.setTableName(tableName);
//				cm.setJavaType(javaType);
//				if(columnTypeHasLength(javaType)){
//					int length = 0;
//					Matcher mLength = colLengthP.matcher(tmp);
//					if(mLength.find()){
//						String lengthStr = mLength.group(1);
//						if(lengthStr.indexOf(",")==-1){
//							length = Integer.valueOf(lengthStr);
//						}else{
//							length = Integer.valueOf(lengthStr.split(",")[0]);
//						}
//					}
//					cm.setLength(length);
//				}
//				cm.setNullAble(nullable);
//				ls.add(cm);
//			}
//		}finally{
//			rs.close();
//			ps.close();
//		}
//		return ls;
//	}
	
//	@Override
//	public String javaType2SQLType(Class<?> javaType){
//		Iterator<Entry<String, Class<?>>> it = types.entrySet().iterator();
//		String type =null;
//		while (it.hasNext()) {
//			Map.Entry<String,Class<?>> entry = it.next();
//			Object obj = entry.getValue();
//			if (javaType.equals(obj)) {
//				type = entry.getKey();
//				break;
//			}
//		}
//		if(type==null){
//			System.err.println("查无此类型");
//		}
//		return type;
//	}
	
//	@Override
//	public Class<?> sqlType2JavaType(String sqlType){
//		Class<?> type = types.get(sqlType.toLowerCase());
//		if(type==null){
//			System.err.println("查无此类型");
//		}
//		return type;
//	}
	
	
	@Override
	public String processSQLVal(Object val,int javaType, ColumnMeta cm){
		if(val==null)return "NULL";
		try {
			switch(javaType){
				case Types.CHAR: 
				case Types.CLOB:
				case Types.VARCHAR: return processStr(String.valueOf(val));
				case Types.DATE: 
					if(String.class.isInstance(val)){
						return "'"+val.toString()+"'";
					}else if(Date.class.isInstance(val)){
						return "'"+dateSDF.format((Date)val)+"'";
					}
				case Types.TIMESTAMP:
					if(String.class.isInstance(val)){
						return "'"+val.toString()+"'";
					}else if(Date.class.isInstance(val)){
						return "'"+dateTimeSDF.format((Date)val)+"'";
					}
				case Types.NUMERIC: 
				case Types.DECIMAL: return BigDecimal.class.cast(val).toString();
				case Types.INTEGER: return Integer.class.cast(val).toString();
				case Types.BIGINT: return Long.class.cast(val).toString();
				case Types.FLOAT: return Float.class.cast(val).toString();
				case Types.VARBINARY:
				case Types.BLOB:
				default:return "NULL";
			}
		} catch (ClassCastException e) {
			e.printStackTrace();
		}
		return "NULL";
	}
	
	@Override
	public boolean columnTypeHasDecimal(int javaType){
		switch(javaType){
			case Types.DECIMAL: 
			case Types.NUMERIC: return true;
			default:return false;
		}
	}
	
	@Override
	public boolean columnTypeHasLength(int javaType){
	    switch(javaType){
	        case Types.CHAR: 
	        case Types.VARCHAR: 
	        case Types.DECIMAL: 
	        case Types.NUMERIC:  return true;
	        
	        case Types.INTEGER:
	        case Types.CLOB:
	        case Types.DATE: 
	        case Types.TIMESTAMP:
	        case Types.VARBINARY:
	        case Types.BLOB:
	        default:return false;
	    }
	}
	
	@Override
	public boolean columnTypeHasLength(ColumnMeta cm,int javaType){
		return columnTypeHasLength(javaType);
	}
	
//	@Override
//	public String processSQLVal(Object val,Class<?> toType){
//		if(val==null)return "NULL";
//		if(String.class.equals(toType)){
//			return "'"+String.valueOf(val)+"'";
//		}else if(Number.class.equals(toType)){
//			if(Integer.class.isInstance(val)){
//				return Integer.class.cast(val).toString();
//			}else if(Float.class.isInstance(val)){
//				return Float.class.cast(val).toString();
//			}else if(Double.class.isInstance(val)){
//				return Double.class.cast(val).toString();
//			}
//		}else if(Integer.class.equals(toType)){
//			if(Integer.class.isInstance(val)){
//				return Integer.class.cast(val).toString();
//			}
//		}else if(Float.class.equals(toType)){
//			if(Float.class.isInstance(val)){
//				return Float.class.cast(val).toString();
//			}
//		}else if(Clob.class.equals(toType)){
//			return val.toString();
//		}else if(Blob.class.equals(toType)){
//			System.err.println("无法处理");
//			return "NULL";
//		}else if(Long.class.equals(toType)){
//			if(Long.class.isInstance(val)){
//				return Long.class.cast(val).toString();
//			}
//		}else if(Date.class.equals(toType)){
//			if(String.class.isInstance(val)){
//				return "to_date("+val.toString()+",'yyyy-MM-dd HH:mm:ss')";
//			}else if(Date.class.isInstance(val)){
//				return "to_date("+sdf.format((Date)val)+",'yyyy-MM-dd HH:mm:ss')";
//			}
//		}
//		System.out.println("什么类型？");
//		return val.toString();
//	}

//	@Override
//	public boolean columnTypeHasLength(Class<?> colType){
//		if(Character.class.equals(colType)){
//			return true;
//		}else if(String.class.equals(colType)){
//			return true;
//		}else if(Boolean.class.equals(colType)){
//			return false;
//		}else if(Integer.class.equals(colType)){
//			return false;
//		}else if(BigInteger.class.equals(colType)){
//			return false;
//		}else if(Float.class.equals(colType)){
//			return true;
//		}else if(Clob.class.equals(colType)){
//			return false;
//		}else if(Blob.class.equals(colType)){
//			return false;
//		}else if(Long.class.equals(colType)){
//			return false;
//		}else if(Date.class.equals(colType)){
//			return false;
//		}else{
//			System.err.println("不支持的类型:["+colType.getName()+"]");
//			return false;
//		}
//	}
//	@Override
//	public int tableNameMaxLength(){
//		return 20;
//	}
//
//	@Override
//	public String[] keywords(){
//		return new String[]{"as"};
//	}
	
	@Override
	protected Map<Integer,String> getTypes() {
		return types;
	}
	@Override
	public String getNamingChar() {
		return "\"";
	}
	
	@Override
	public String getConcatStr(String a,String b){
		return a+" + "+b;
	}

	@Override
	public List<String> buildClobSql(TableMeta targetTM, String columnName,
			Map<String, Object> v) throws SQLException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String getPaginationSql(String selectSql,
			String tablename,
			String tAlias,
			String pk,
			String fromTableSql,
			String orderBySql,String whereSql, int curPageNo, int pageSize) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String getModifyColumnKey() {
		return "modify";
	}
}
